#pragma once

// #include <so_math.h>
#include <Vector2.h>
#include <Shape2D.h>
class Entity;
struct AABB
{
    Vector2 ul, dr;
    inline AABB() : ul(Vector2()), dr(Vector2()) {}
    inline AABB(const Vector2 &ul, const Vector2 &dr) : ul(ul), dr(dr) {};
    inline real getWidth() const
    {
        return dr.x - ul.x;
    }
    inline real getHeight() const
    {
        return dr.y - ul.y;
    }
};
class CollisionEntity : public Shape2D
{
protected:
    Entity *parent = nullptr;
    Vector2 position;
    AABB aabb;
    bool fixed = false;

public:
    Vector2 getPosition() const;
    Entity *getParent();
    virtual void updatePosition(const Vector2 &pos) = 0;
    ;
    void setParent(Entity *parent = nullptr);
    virtual bool contain(CollisionEntity *entity) const = 0;
    virtual Vector2 contact(CollisionEntity *entity) const = 0;
    const AABB *getAABB() const;
    int layer = 0;
    void setFixed(bool val);
    bool isFixed();
};

class CollisionEntityCircle : public CollisionEntity, public Circle
{
public:
    CollisionEntityCircle(real radius, Entity *parent = nullptr);
    bool contain(CollisionEntity *entity) const override;
    Vector2 contact(CollisionEntity *entity) const override;
    void updatePosition(const Vector2 &pos) override;
};
class CollisionEntityRectangle : public CollisionEntity, public Rectangle
{
public:
    CollisionEntityRectangle(const Vector2 &size, Entity *parent = nullptr);
    bool contain(CollisionEntity *entity) const override;
    Vector2 contact(CollisionEntity *entity) const override;
    void updatePosition(const Vector2 &pos) override;
};